const request = require('request');
const config = require('_/config');
const db = require('db/user.js');
const dbCar = require('db/car.js');
const dbVip = require('db/vip.js');
const dbPackage = require('db/package.js');
const jwtToken = require('lib/utils/jwtToken.js');
const common = require('lib/utils/common');
const dbRecord = require('db/record.js');
const dbPlace = require('db/place.js');
const dbReservation = require('db/reservation.js');

/** @name 登录-微信小程序 **/
exports.login = async ctx => {
  if(ctx.requiredParams(['code'])) return;
  const { code } = ctx.request.body;
	const result = await getInfo(code); // {session_key, expires_in, openid}
	const { openid } = JSON.parse(result);
	let userList = await db.yd_findOpenId(openid);
	const currentTime = common.YD_dateFormat();
	if (userList.length) {
		session(ctx, userList[0]);
	} else {
		const options = {
			uuid: common.YD_generateUUID(),
			openId: openid,
			note: '微信小程序用户',
			role: 1,
			status: 1,
			createTime: currentTime,
			updateTime: currentTime,
		}
		await db.yd_add(options)
		userList = await db.yd_findOpenId(openid);
		session(ctx, userList[0]);
	}
	// 更新登录时间
	db.yd_updateLastTime({
		uuid: userList[0].uuid,
		lastTime: currentTime,
		updateTime: currentTime,
	})
};

/** @name 获取openId **/
function getInfo(code) {
	const url =  `https://api.weixin.qq.com/sns/jscode2session?appid=${config.wx.appId}&secret=${config.wx.appSecret}&js_code=${code}&grant_type=authorization_code`;
	return new Promise((resolve, reject) => {
		request(url, (error, response, body) => {
			if(response.statusCode === 200) {
				resolve(body)
			}else {
				reject(error)
			}
		});
	})
}

/** @name 处理登录状态 **/
async function session(ctx, userInfo) {
	if(userInfo.status !== 1) return ctx.fail('账号被锁定，你做了不可描述的事？-.-');
	const token = await jwtToken.createToken({userInfo: userInfo.uuid});
	ctx.session.token = token;
	ctx.session.userInfo = userInfo;
	ctx.success({
		uuid: userInfo.uuid,
		role: userInfo.role,
		status: userInfo.status,
		lastTime: userInfo.lastTime,
		createTime: userInfo.createTime,
		updateTime: userInfo.updateTime,
		token: token,
		nickname: userInfo.nickname,
		avatar: userInfo.avatar,
	}, '欢迎进入');
}

/** @name 获取用户信息 **/
exports.userInfo = async ctx => {
	const { uuid } = ctx.session.userInfo;
  await db.yd_query(uuid).then(async res => {
    if(res.length) {
      const user = res[0];
      ctx.success({
        uuid: user.uuid,
        username: user.username,
        nickname: user.nickname,
        avatar: user.avatar,
        gender: user.gender,
        note: user.note,
        role: user.role,
        status: user.status,
        lastTime: user.lastTime,
        createTime: user.createTime,
        updateTime: user.updateTime,
        token: ctx.session.token
			});
    }else {
      ctx.fail('用户信息查询失败');
    }
  });
};

/** @name 用户授权 **/
exports.auth = async ctx => {
	const { avatar, nickname }  = ctx.request.body;
	const currentTime = common.YD_dateFormat()
	const options = {
		updateTime: currentTime,
	}
	if (avatar) options.avatar = avatar;
	if (nickname) options.nickname = nickname;
	console.log('options', options)
	await db.yd_update(options, { uuid: ctx.session.userInfo.uuid });
	ctx.success('用户授权成功');
};

/** @name 绑定车辆 **/
exports.bindCar = async ctx => {
	if(ctx.requiredParams(['number'])) return;
	const { number, color, images } = ctx.request.body;
	const { uuid } = ctx.session.userInfo;
	const result = await dbCar.yd_find({ number });
	if(result.length > 0) {
		const car = result[0];
		if (car.userId) {
			ctx.fail('该车牌号码已经被绑定');
		} else {
			const options = {
				userId: uuid,
				color,
				images,
				updateTime: common.YD_dateFormat(),
			}
			await dbCar.yd_update(options, { number });
			ctx.success('绑定成功');
		}
	}else {
		const options = {
			number,
			userId: uuid,
			color,
			images,
			status: 0,
			createTime: common.YD_dateFormat(),
			updateTime: common.YD_dateFormat(),
		}
		await dbCar.yd_add(options);
		ctx.success('绑定成功');
	}
};

/** @name 获取用户绑定车辆 **/
exports.getCarList = async ctx => {
	const { uuid } = ctx.session.userInfo;
  const rows = await dbCar.yd_userCarlist({ userId: uuid });
	ctx.success({
    rows
  });
};

/** @name 会员开通预支付 **/
exports.vipPrePay = async ctx => {
	if(ctx.requiredParams(['number', 'packageId'])) return;
	const { number, packageId } = ctx.request.body;
	const { uuid } = ctx.session.userInfo;
	const currentTime = common.YD_dateFormat();
	const orderCode = common.YD_getOrderCode();
	const packageResult = await dbPackage.yd_find({ id: packageId });
	const vipViceResult = await dbVip.yd_findVice({ number: number, packageId: packageId });
	if (vipViceResult.length > 0 && vipViceResult[0].status === 0) {
		ctx.success({
			orderCode: vipViceResult[0].orderCode,
			package: packageResult[0]
		}, '存在未支付的预支付订单');
	} else {
		const options = {
			number,
			packageId,
			userId: uuid,
			orderCode, // TODO: P4
			status: 0,
			payType: 'wx_pay',
			createTime: currentTime,
			updateTime: currentTime,
		}
		await dbVip.yd_addVice(options);
		ctx.success({
			orderCode,
			package: packageResult[0]
		}, '预支付成功创建');
	}
};

/** @name 会员开通支付 **/
exports.vipPay = async ctx => {
	if(ctx.requiredParams(['number', 'packageId', 'payType'])) return;
	const { number, packageId, payType } = ctx.request.body;
	const { uuid } = ctx.session.userInfo;
	const currentTime = common.YD_dateFormat();
	const packageResult = await dbPackage.yd_find({ id: packageId });
	const vipViceResult = await dbVip.yd_findVice({ number: number, packageId: packageId });
	if (vipViceResult.length > 0) {
		const options = {
			status: 1,
			payType,
			updateTime: currentTime,
		}
		// TODO: 已经支付的不能再支付
		await dbVip.yd_updateVice(options, { number, packageId: parseInt(packageId) });
		const vipResult = await dbVip.yd_find({ number });
		if (vipResult.length > 0) {
			const options = {
				packageId,
				endTime: common.YD_getFeatureDate(packageResult[0].value, new Date(vipResult[0].endTime))
			}
			// TODO: 还要考虑已经开通自由车位再开通固定车位的情况
			await dbVip.yd_update(options, { id: vipResult[0].id });
		}else {
			const options = {
				number,
				packageId,
				userId: uuid,
				startTime: currentTime,
				endTime: common.YD_getFeatureDate(packageResult[0].value)
			}
			await dbVip.yd_add(options)
		}
		ctx.success({ id: vipViceResult[0].id }, '支付成功');
	}
};

/** @name 获取支付信息 **/
exports.getVipPayInfo = async ctx => {
	if(ctx.requiredParams(['id'])) return;
	const { id } = ctx.query;
	const result = await dbVip.yd_queryVice({ id: parseInt(id) });
	ctx.success({ ...result[0] }, '获取支付信息成功');
};

/** @name 获取会员统计 **/
exports.getVipStatistics = async ctx => {
	const { uuid } = ctx.session.userInfo;
  const carList = await dbCar.yd_userCarlist({ userId: uuid });
	const carCount = carList.length;
	let vipList = await dbVip.yd_findVip({ userId: uuid });
	vipList = vipList.filter(item => common.YD_compareDate(item.endTime, new Date(), true) !== -1);
	const vipCount = vipList.length;
	const parkingCount = carList.reduce((a, b) => a + b.count, 0);
	ctx.success({
    carCount,
		vipCount,
		parkingCount
  }, '会员统计查询成功');
};

/** @name 查询已停放车辆信息 **/
exports.getRecordInfo = async ctx => {
	if(ctx.requiredParams(['number'])) return;
	const { number } = ctx.query;
	const currentTime = common.YD_dateFormat();
	const findResult = await dbRecord.yd_find({ number });
	if (findResult.length > 0){
		if(findResult.length > 1) {
			ctx.fail('查询异常，请联系管理人员');
		} else {
			const findItem = findResult[0];
			// 计算停车时长
			findItem.time = common.YD_timeInterval(findItem.startTime, common.YD_dateFormat())
			// 获取套餐信息
			const packageResult = await dbPackage.yd_findCode({ code: 'temp_package' });
			const packageInfo = packageResult[0];
			// 会员车辆
			const vipResult = await dbVip.yd_find({ number });
			if (vipResult.length) {
				// TODO: 其他操作
				findItem.price = 0;
			}else {
				// 停车小时数
				const hours = common.YD_getTimeIntervalHours(findItem.startTime, common.YD_dateFormat());
				// 计算停车金额
				findItem.price = hours * packageInfo.price;
				// 同步到数据库
				await dbRecord.yd_update({
					pay: findItem.price,
					updateTime: currentTime,
				}, {
					id: findItem.id
				})
			}
			ctx.success(findItem, '查询成功');
		}
	} else {
		ctx.success(null, '查询成功');
	}
};

/** @name 停车缴费 **/
exports.parkingPay = async ctx => {
	if(ctx.requiredParams(['number', 'payType'])) return;
	const { number, payType } = ctx.request.body;
	const { uuid } = ctx.session.userInfo;
	const currentTime = common.YD_dateFormat();
	const findResult = await dbRecord.yd_find({ number });
	const findItem = findResult[0];
	// TODO: 只能是未支付的订单
	const options = {
		userId: uuid,
		status: 1,
		payType,
		note: '微信小程序上缴费',
		endTime: currentTime,
		updateTime: currentTime,
	}
	await dbRecord.yd_update(options, { id: findItem.id });
	ctx.success('支付成功');
};

/** @name 模拟停车记录 **/
exports.imitate = async ctx => {
	if(ctx.requiredParams(['number'])) return;
	const { number } = ctx.request.body;
	const { uuid } = ctx.session.userInfo;
	const currentTime = common.YD_dateFormat()
	const options = {
		number,
		userId: uuid,
		status: 0,
		orderCode: common.YD_getOrderCode(),
		startTime: currentTime,
		updateTime: currentTime,
		note: '微信小程序模拟停车记录'
	}
	// 车位信息
	const placeInfo = await updatePlace(options);
	if(!placeInfo) return ctx.fail('暂无空闲车位，无法分配');
	options.placeId = placeInfo.id;

	await dbRecord.yd_add(options);
	ctx.success('模拟成功');
};

/** @name 需要同步车位信息、并可能随机分配一个车位 **/
async function updatePlace(options) {
	const placeList = await dbPlace.yd_easyList();
	const fixedPlaceResult = placeList.find(place => place.type === 1 && place.number === options.number);
	if (fixedPlaceResult) { // 固定车位
		await dbPlace.yd_update({ idle: options.status === 0 ? 1 : 0 }, { id: fixedPlaceResult.id })
		return fixedPlaceResult;
	} else { // 非固定车位
		let place = null;
		if (options.status === 0) {
			const residuePlace = placeList.filter(place => place.type === 0 && place.idle === 0);
			if(residuePlace.length <= 0) return null; // 没有车位
			const random = Math.floor(Math.random() * residuePlace.length);
			place = residuePlace[random];
			await dbPlace.yd_update({ idle: 1, number: options.number, userId: options.userId }, { id: place.id })
		}
		return place;
	}
}

/** @name 获取会员车辆 **/
exports.getVipCar = async ctx => {
	const { uuid } = ctx.session.userInfo;
	let vipList = await dbVip.yd_findVip({ userId: uuid });
	vipList = vipList.filter(item => common.YD_compareDate(item.endTime, new Date(), true) !== -1);
	ctx.success({
    rows: vipList
  }, '会员车辆查询成功');
};

/** @name 获取空闲车位 **/
exports.getPlaceIdle = async ctx => {
	const rows = await dbPlace.yd_easyList();
	ctx.success({
    rows: rows.filter(place => place.idle === 0 && place.type === 0)
  });
};

/** @name 预约 **/
exports.reservation = async ctx => {
	if(ctx.requiredParams(['number', 'placeId', 'date'])) return;
	const { number, placeId, date, note } = ctx.request.body;
	const { uuid } = ctx.session.userInfo;
	const currentTime = common.YD_dateFormat()
	const options = {
		number,
		userId: uuid,
		placeId: parseInt(placeId),
		status: 0,
		startTime: date, // TODO: P7
		createTime: currentTime,
		updateTime: currentTime,
		note
	}
	// TODO: 要判断时间如果预约过了就不能重复预约了
	await dbReservation.yd_add(options);
	ctx.success('用户预约成功');
};
